import json
import re

from django import http
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator, EmptyPage
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from pymysql import DatabaseError

from apps.orders.models import OrderInfo
from apps.users.models import User
from utils import constants
from utils.emails import Email
from utils.response_code import RETCODE


class RegisterView(View):
    def get(self, request):
        return render(request, 'register.html')

    def post(self, request):
        json_data = json.loads(request.body.decode())
        username = json_data.get('username')
        phone = json_data.get('phone')
        password = json_data.get('password')
        password2 = json_data.get('password2')
        allow = json_data.get('allow')
        print(username,phone,password,password2,allow)

        if not all([username,phone,password, password2]):
            return http.JsonResponse('缺少参数')
        # 判断用户名是否在5-20个字符
        if re.match(r'^a-zA-Z0-9_{5,20}$', username):
            return http.JsonResponse('用户名输入错误')
        # 手机号是否正确
        if not re.match(r'^1[3-9]\d{9}$', phone):
            return http.JsonResponse('手机号输入不正确')
        # 判断密码是否在8-20的字符
        if re.match(r'^a-zA-Z0-9_{8,20}$', password):
            return http.JsonResponse('密码输入不正确')
        # 判断两次密码是否一致
        if password != password2:
            return http.JsonResponse('两次密码输入不一致')
        # 是否同意勾选
        if allow != 'on':
            return http.JsonResponse('请勾选协议')

        # 保存数据到数据库
        try:
            user = User.objects.create_user(username=username, password=password, phone=phone)
        except DatabaseError:
            return render(request, 'register.html', {'register_errmsg': '注册失败'})

        login(request, user)

        # return http.HttpResponse('注册成功，重定向到首页')
        # return render(request,'index.html')
        response = http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)
        return response

class UsernameCountView(View):
    '''判断用户名是否重复注册'''

    def get(self, request, username):
        """
        :param request:请求对象
        :param username: 用户名
        :return: JSON
        """
        count = User.objects.filter(username=username).count()
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'count': count})

class MobileCountView(View):
    """判断手机号是否重复"""

    def get(self, request, mobile):
        """
        :param request:
        :param mobile:
        :return:
        """
        count = User.objects.filter(mobile=mobile).count()
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'count': count})

class LoginView(View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        # 获取参数
        json_data = json.loads(request.body.decode())
        username = json_data.get('username')
        password = json_data.get('password')
        remember = json_data.get('remember')

        print(username,password,remember)
        # 校验参数
        if not all([username, password]):
            return http.JsonResponse('缺少参数',safe=False)
        if not re.match(r'^[a-zA-Z0-9_]{5,20}$', username):
            return http.JsonResponse('用户名输入错误')
        if not re.match(r'^[a-zA-Z0-9_]{8,20}$', password):
            return http.JsonResponse('密码输入不正确')
        print(222222222)
        # 认证登录用户
        user = authenticate(username=username, password=password)
        print(username,password)
        if user is None:
            return render(request, 'login.html', {'account_errmsg': '用户名或密码输入不正确'})


        # 状态保持
        login(request, user)  # 它会指定的事情1.在本本地服务器端存储session数据2.修改响应头信息 添加set-cookie：session=...
        # 设置状态保持周期
        if remember != 'on':
            # 没有选记住用户，浏览会话记录过期
            request.session.set_expiry(0)
        else:
            # 选择记住，两周后过期
            request.session.set_expiry(None)

        # 响应登录结果，获取查询参数next 有next就重定向next后的页面，没有就重定向到主页
        # 查看用户中心获取到next参数
        # next = request.GET.get('next')
        # if next:
        #     response = redirect(next)
        # else:
        #     response = redirect(reverse('index:index'))

        #购物车合并信息
        # response = merge_cart_cookie_to_redis(request=request,user=user,response=response)
        # 注册时用户名写入到cookie里，并设置cookie有效时间15天
        response = http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)
        return response

class LogoutView(View):
    """退出登录"""

    def get(self, request):
        logout(request)
        # 退出登录，重定向到主页
        response = redirect(reverse('index:index'))
        # 清除cookie中存储的username
        response.delete_cookie('username')
        return response

class UserCenterView(LoginRequiredMixin,View):
    def get(self,request):
        """提供个人信息页面"""
        context = {
            'username': request.user.username,
            'phone': request.user.phone,
            'password':request.user.password
        }
        return render(request,'user_center.html',context)

class ChangePasswordView(LoginRequiredMixin,View):
    def get(self,request):
        return render(request,'user_center_pass.html')

    def post(self, request):
        """实现修改密码逻辑"""
        # 获取参数
        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        new_password2 = request.POST.get('new_password2')
        # 校验参数
        if not all([old_password, new_password, new_password2]):
            return http.HttpResponseBadRequest('缺少参数')
        # 校验新密码
        if not re.match(r'^[a-zA-Z0-9_]{5,20}$', new_password):
            return http.HttpResponseBadRequest('密码输入有误')
        if new_password != new_password2:
            return http.HttpResponseBadRequest('两次密码不一致')

        #校验旧密码是否正确
        if not request.user.check_password(old_password):
            return render(request,'user_center_pass.html',{'origin_password_errmsg':'原密码有误'})

        try:
            request.user.set_password(new_password)
            request.user.save()
        except Exception as e:
            return render(request,'user_center_pass.html',{'change_password_errmsg':'修改密码失败'})


        #修改完密码需要退出登录
        logout(request)

        response = redirect(reverse('users:login'))

        response.delete_cookie('username')
        return response

class MyOrderView(LoginRequiredMixin,View):
    def get(self,request,page_num):
        user = request.user
        # 查询订单
        orders = user.orderinfo_set.all().order_by('-create_time')
        print(orders)
        # 遍历所有订单
        for order in orders:
            # 绑定订单状态
            order.status_name = OrderInfo.ORDER_STATUS_CHOICES[order.status - 1][1]
            # print(order.status_name)
            # 绑定支付方式
            order.pay_method_name = OrderInfo.PAY_METHOD_CHOICES[order.pay_method - 1][1]
            # print(order.pay_method)
            order.food_list = []
            # 查询订单商品
            order_foods = order.skus.all()
            # 遍历订单商品
            for order_food in order_foods:
                food = order_food.food
                food.count = order_food.count
                food.amount = food.price * food.count
                order.food_list.append(food)
                print(order.food_list)

        # 分页
        page_num = int(page_num)
        print(page_num)
        try:
            pagiantor = Paginator(orders, constants.ORDERS_LIST_LIMIT)
            page_orders = pagiantor.page(page_num)
            total_page = pagiantor.num_pages
        except EmptyPage:
            return http.HttpResponseNotFound('订单不存在')
        context={
            'username':request.user.username,
            'phone':request.user.phone,
            'page_orders': page_orders,
            'total_page': total_page,
            'page_num': page_num,
        }
        return render(request,'user_order.html',context)